package interview.sort;

import com.study.interfaces.IArraySort;
import org.junit.Test;

import static com.study.util.LogUtil.info;
import static java.util.Arrays.copyOfRange;

/**
 * 5. 归并排序
 * <p>
 * 申请空间，使其大小为两个已经排序序列之和，该空间用来存放合并后的序列；
 * 设定两个指针，最初位置分别为两个已经排序序列的起始位置；
 * 比较两个指针所指向的元素，选择相对小的元素放入到合并空间，并移动指针到下一位置；
 * 重复步骤 3 直到某一指针达到序列尾；
 * 将另一序列剩下的所有元素直接复制到合并序列尾。
 */
public class MergeSort implements IArraySort {

    @Override
    public int[] sort(int[] arr) {
        if (arr.length < 2) {
            return arr;
        }
        int middle = (int) Math.floor(arr.length / 2);

        int[] left = copyOfRange(arr, 0, middle);

        int[] right = copyOfRange(arr, middle, arr.length);

        return merge(sort(left), sort(right));
    }

    protected int[] merge(int[] left, int[] right) {

        int[] result = new int[left.length + right.length];
        int i = 0;
        while (left.length > 0 && right.length > 0) {

            if (left[0] <= right[0]) {
                result[i++] = left[0];
                left = copyOfRange(left, 1, left.length);
            } else {
                result[i++] = right[0];
                right = copyOfRange(right, 1, right.length);
            }
        }

        while (left.length > 0) {
            result[i++] = left[0];
            left = copyOfRange(left, 1, left.length);
        }

        while (right.length > 0) {
            result[i++] = right[0];
            right = copyOfRange(right, 1, right.length);
        }

        return result;
    }

    @Test
    public void test() {
        info(sort(new int[]{2, 1, 5, 3, 4, 9, 8, 7, 10}));
    }
}